// (C) 2022 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Intel Program License Subscription 
// Agreement, Intel FPGA IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Intel and sold by 
// Intel or its authorized distributors.  Please refer to the applicable 
// agreement for further details.

module A_cse_ocs_dpa_aes10c_affine
   #(
      parameter AFFINE_MAP_ROW7 = 8'b01011000,
      parameter AFFINE_MAP_ROW6 = 8'b11110100,
      parameter AFFINE_MAP_ROW5 = 8'b01110010,
      parameter AFFINE_MAP_ROW4 = 8'b00110101,
      parameter AFFINE_MAP_ROW3 = 8'b01000001,
      parameter AFFINE_MAP_ROW2 = 8'b10101110,
      parameter AFFINE_MAP_ROW1 = 8'b10010011,
      parameter AFFINE_MAP_ROW0 = 8'b10101011,
      parameter MB = 8'b11001111 
    )
   (
      input  logic [7:0] in,
      output logic [7:0] out );

   logic [7:0] outA;

   assign outA[7] = (AFFINE_MAP_ROW7[0]&in[0])^(AFFINE_MAP_ROW7[1]&in[1])^(AFFINE_MAP_ROW7[2]&in[2])^(AFFINE_MAP_ROW7[3]&in[3])^(AFFINE_MAP_ROW7[4]&in[4])^(AFFINE_MAP_ROW7[5]&in[5])^(AFFINE_MAP_ROW7[6]&in[6])^(AFFINE_MAP_ROW7[7]&in[7]);
   assign outA[6] = (AFFINE_MAP_ROW6[0]&in[0])^(AFFINE_MAP_ROW6[1]&in[1])^(AFFINE_MAP_ROW6[2]&in[2])^(AFFINE_MAP_ROW6[3]&in[3])^(AFFINE_MAP_ROW6[4]&in[4])^(AFFINE_MAP_ROW6[5]&in[5])^(AFFINE_MAP_ROW6[6]&in[6])^(AFFINE_MAP_ROW6[7]&in[7]);
   assign outA[5] = (AFFINE_MAP_ROW5[0]&in[0])^(AFFINE_MAP_ROW5[1]&in[1])^(AFFINE_MAP_ROW5[2]&in[2])^(AFFINE_MAP_ROW5[3]&in[3])^(AFFINE_MAP_ROW5[4]&in[4])^(AFFINE_MAP_ROW5[5]&in[5])^(AFFINE_MAP_ROW5[6]&in[6])^(AFFINE_MAP_ROW5[7]&in[7]);
   assign outA[4] = (AFFINE_MAP_ROW4[0]&in[0])^(AFFINE_MAP_ROW4[1]&in[1])^(AFFINE_MAP_ROW4[2]&in[2])^(AFFINE_MAP_ROW4[3]&in[3])^(AFFINE_MAP_ROW4[4]&in[4])^(AFFINE_MAP_ROW4[5]&in[5])^(AFFINE_MAP_ROW4[6]&in[6])^(AFFINE_MAP_ROW4[7]&in[7]);
   assign outA[3] = (AFFINE_MAP_ROW3[0]&in[0])^(AFFINE_MAP_ROW3[1]&in[1])^(AFFINE_MAP_ROW3[2]&in[2])^(AFFINE_MAP_ROW3[3]&in[3])^(AFFINE_MAP_ROW3[4]&in[4])^(AFFINE_MAP_ROW3[5]&in[5])^(AFFINE_MAP_ROW3[6]&in[6])^(AFFINE_MAP_ROW3[7]&in[7]);
   assign outA[2] = (AFFINE_MAP_ROW2[0]&in[0])^(AFFINE_MAP_ROW2[1]&in[1])^(AFFINE_MAP_ROW2[2]&in[2])^(AFFINE_MAP_ROW2[3]&in[3])^(AFFINE_MAP_ROW2[4]&in[4])^(AFFINE_MAP_ROW2[5]&in[5])^(AFFINE_MAP_ROW2[6]&in[6])^(AFFINE_MAP_ROW2[7]&in[7]);
   assign outA[1] = (AFFINE_MAP_ROW1[0]&in[0])^(AFFINE_MAP_ROW1[1]&in[1])^(AFFINE_MAP_ROW1[2]&in[2])^(AFFINE_MAP_ROW1[3]&in[3])^(AFFINE_MAP_ROW1[4]&in[4])^(AFFINE_MAP_ROW1[5]&in[5])^(AFFINE_MAP_ROW1[6]&in[6])^(AFFINE_MAP_ROW1[7]&in[7]);
   assign outA[0] = (AFFINE_MAP_ROW0[0]&in[0])^(AFFINE_MAP_ROW0[1]&in[1])^(AFFINE_MAP_ROW0[2]&in[2])^(AFFINE_MAP_ROW0[3]&in[3])^(AFFINE_MAP_ROW0[4]&in[4])^(AFFINE_MAP_ROW0[5]&in[5])^(AFFINE_MAP_ROW0[6]&in[6])^(AFFINE_MAP_ROW0[7]&in[7]);

generate
if (1) begin
   assign out[7] = outA[7] ^ MB[7];
   assign out[6] = outA[6] ^ MB[6];
   assign out[5] = outA[5] ^ MB[5];
   assign out[4] = outA[4] ^ MB[4];
   assign out[3] = outA[3] ^ MB[3];
   assign out[2] = outA[2] ^ MB[2];
   assign out[1] = outA[1] ^ MB[1];
   assign out[0] = outA[0] ^ MB[0];
end

if (0) begin
 assign out[7] = (outA[7]);
 assign out[6] = (outA[6]);
 assign out[5] = (outA[5]);
 assign out[4] = (outA[4]);
 assign out[3] = (outA[3]);
 assign out[2] = (outA[2]);
 assign out[1] = (outA[1]);
 assign out[0] = (outA[0]);
end

if (0) begin
 assign out[7] = ~(outA[7]);
 assign out[6] = ~(outA[6]);
 assign out[5] = ~(outA[5]);
 assign out[4] = ~(outA[4]);
 assign out[3] = ~(outA[3]);
 assign out[2] = ~(outA[2]);
 assign out[1] = ~(outA[1]);
 assign out[0] = ~(outA[0]);
end
endgenerate
endmodule


